From: Chris Swindle Date: Tue, 3 Oct 2017 08:36:46 +0000 (+0100) Subject: Add support for publish to take a registry that should be used. X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~5^2~1^2~11 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=345c03d4cfbd34e2ccb1c634a21fa7f624452e7d;p=cargo.git Add support for publish to take a registry that should be used. --- diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index d8c3710ed..7b52ec579 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -29,7 +29,7 @@ pub struct Manifest { include: Vec, metadata: ManifestMetadata, profiles: Profiles, - publish: bool, + publish: Option>, replace: Vec<(PackageIdSpec, Dependency)>, patch: HashMap>, workspace: WorkspaceConfig, @@ -239,7 +239,7 @@ impl Manifest { links: Option, metadata: ManifestMetadata, profiles: Profiles, - publish: bool, + publish: Option>, replace: Vec<(PackageIdSpec, Dependency)>, patch: HashMap>, workspace: WorkspaceConfig, @@ -276,7 +276,7 @@ impl Manifest { pub fn version(&self) -> &Version { self.package_id().version() } pub fn warnings(&self) -> &[DelayedWarning] { &self.warnings } pub fn profiles(&self) -> &Profiles { &self.profiles } - pub fn publish(&self) -> bool { self.publish } + pub fn publish(&self) -> &Option> { &self.publish } pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] { &self.replace } pub fn original(&self) -> &TomlManifest { &self.original } pub fn patch(&self) -> &HashMap> { &self.patch } diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index dc54497ec..9fc9e91ad 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -94,7 +94,7 @@ impl Package { pub fn targets(&self) -> &[Target] { self.manifest.targets() } pub fn version(&self) -> &Version { self.package_id().version() } pub fn authors(&self) -> &Vec { &self.manifest.metadata().authors } - pub fn publish(&self) -> bool { self.manifest.publish() } + pub fn publish(&self) -> &Option> { self.manifest.publish() } pub fn has_custom_build(&self) -> bool { self.targets().iter().any(|t| t.is_custom_build()) diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 42ff2f872..3499a3e5a 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -41,10 +41,14 @@ pub struct PublishOpts<'cfg> { pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> { let pkg = ws.current()?; - if !pkg.publish() { - bail!("some crates cannot be published.\n\ - `{}` is marked as unpublishable", pkg.name()); + if let &Some(ref allowed_registries) = pkg.publish() { + let index = opts.index.clone(); + if index.is_none() || !allowed_registries.contains(&index.unwrap()) { + bail!("some crates cannot be published.\n\ + `{}` is marked as unpublishable", pkg.name()); + } } + if !pkg.manifest().patch().is_empty() { bail!("published crates cannot contain [patch] sections"); } diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index c2220ac2d..d8aaada23 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -380,6 +380,44 @@ impl<'de> de::Deserialize<'de> for StringOrBool { } } +#[derive(Clone, Debug, Serialize)] +#[serde(untagged)] +pub enum VecStringOrBool { + VecString(Vec), + Bool(bool), +} + +impl<'de> de::Deserialize<'de> for VecStringOrBool { + fn deserialize(deserializer: D) -> Result + where D: de::Deserializer<'de> + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = VecStringOrBool; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a boolean or vector of strings") + } + + fn visit_seq(self, v: V) -> Result + where V: de::SeqAccess<'de> + { + let seq = de::value::SeqAccessDeserializer::new(v); + Vec::deserialize(seq).map(VecStringOrBool::VecString) + } + + fn visit_bool(self, b: bool) -> Result + where E: de::Error, + { + Ok(VecStringOrBool::Bool(b)) + } + } + + deserializer.deserialize_any(Visitor) + } +} + #[derive(Deserialize, Serialize, Clone, Debug)] pub struct TomlProject { name: String, @@ -389,7 +427,7 @@ pub struct TomlProject { links: Option, exclude: Option>, include: Option>, - publish: Option, + publish: Option, workspace: Option, #[serde(rename = "im-a-teapot")] im_a_teapot: Option, @@ -648,7 +686,11 @@ impl TomlManifest { } }; let profiles = build_profiles(&me.profile); - let publish = project.publish.unwrap_or(true); + let publish = match project.publish { + Some(VecStringOrBool::VecString(ref vecstring)) => Some(vecstring.clone()), + Some(VecStringOrBool::Bool(false)) => Some(vec![]), + _ => None, + }; let empty = Vec::new(); let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); let features = Features::new(cargo_features, &mut warnings)?; diff --git a/tests/publish.rs b/tests/publish.rs index ea4986195..d38dcaed1 100644 --- a/tests/publish.rs +++ b/tests/publish.rs @@ -494,3 +494,80 @@ See [..] // Ensure the API request wasn't actually made assert!(!publish::upload_path().join("api/v1/crates/new").exists()); } + +#[test] +fn index_not_in_publish_list() { + publish::setup(); + + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish = [ + "test" + ] + "#) + .file("src/main.rs", "fn main() {}"); + + assert_that(p.cargo_process("publish") + .arg("--index").arg(publish::registry().to_string()), + execs().with_status(101).with_stderr("\ +[ERROR] some crates cannot be published. +`foo` is marked as unpublishable +")); +} + +#[test] +fn publish_empty_list() { + publish::setup(); + + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish = [] + "#) + .file("src/main.rs", "fn main() {}"); + + assert_that(p.cargo_process("publish") + .arg("--index").arg(publish::registry().to_string()), + execs().with_status(101).with_stderr("\ +[ERROR] some crates cannot be published. +`foo` is marked as unpublishable +")); +} + +#[test] +fn publish_allowed_index() { + publish::setup(); + + let p = project("foo"); + p.build(); + + repo(&paths::root().join("foo")) + .file("Cargo.toml", &format!(r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + publish = ["{}"] + "#, publish::registry().to_string())) + .file("src/main.rs", "fn main() {}") + .build(); + + assert_that(p.cargo("publish") + .arg("--index").arg(publish::registry().to_string()), + execs().with_status(0)); +}